<?php
/**
 * Created by PhpStorm.
 * User: xiangfeng
 * Date: 2022/4/9
 * Time: 8:36 AM
 */

namespace app\api\extend\tools;

use app\api\http\exceptions\ResponseJson;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\ValidationData;

class JwtAuth
{
    use ResponseJson;
    /**
     * Jwt token
     * @var
     */
    private $token;

    /**
     * decode Jwt token
     * @var
     */
    private $decodeToken;

    /**
     * claim iss
     * @var string
     */
    private $iss = 'auction.cloudinlink.com';

    /**
     * claim aud
     * @var string
     */
    private $aud = 'qtzj_app_api';

    /**
     * claim uid
     * @var
     */
    private $uid;

    /**
     * claim rid
     * @var
     */
    private $rid;

    /**
     * claim phone
     * @var
     */
    private $phone;

    /**
     * claim secret
     * @var string
     */
    private $secret = "^#!@)*_!(+$)+@!)@!**(#)!*)*^%^%!*&(!";
    /**
     * 单例模式 jwtAuth句柄
     * @var
     */
    private static $instance;

    /**
     * 获取jwtAuth句柄
     * @return JwtAuth
     */
    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 私有化构造函数
     * JwtAuth constructor.
     */

    private function __construct()
    {
    }

    /**
     * 私有化clone函数
     */
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 获取token
     * @return string
     */
    public function getToken()
    {
        return (string)$this->token;
    }

    /**
     * 设置token
     * @param $token
     * @return $this
     */
    public function setToken($token)
    {
        $this->token = $token;
        return $this;
    }

    /**
     * 设置uid
     * @param $uid
     * @return $this
     */
    public function setUid($uid)
    {
        $this->uid = $uid;
        return $this;
    }

    /**
     * 设置rid
     * @param $rid
     * @return $this
     */
    public function setRid($rid)
    {
        $this->rid = $rid;
        return $this;
    }

    /**
     * 编码jwt token
     * @return $this
     */
    public function encode_jwt_token()
    {
        $time = time();
        $this->token = (new Builder())->setHeader('alg', 'HS256')
            ->setIssuer($this->iss)
            ->setAudience($this->aud)
            ->setIssuedAt($time)
            ->setExpiration($time + 30 * 24 * 3600)
            ->set('uid', $this->uid)
            ->set('rid', $this->rid)
            //->set('phone',$this->phone)
            ->sign(new Sha256(), $this->secret)
            ->getToken();
        return $this;
    }

    /**
     * 解码jwt token
     * /**
     * @return \Lcobucci\JWT\Token
     */
    public function decode_jwt_token()
    {
        if (!$this->decodeToken) {
            $this->decodeToken = (new Parser())->parse((string)$this->token);
            $this->uid = $this->decodeToken->getClaim('uid');
            $this->rid = $this->decodeToken->getClaim('rid');
        }
        return $this->decodeToken;
    }

    /**
     * validate token
     * @return bool
     */
    public function validateToken()
    {
        $data = new ValidationData();
        $data->setIssuer($this->iss);
        $data->setAudience($this->aud);
        return $this->decode_jwt_token()->validate($data);
    }

    /**
     * 验证token是否被篡改
     * @return bool
     */
    public function verifyToken()
    {
        $result = $this->decode_jwt_token()->verify(new Sha256(), $this->secret);
        return $result;
    }

}